package com.gxa.clientkill.controller;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gxa.clientkill.pojo.Kill;
import com.gxa.clientkill.service.KillService;
import com.gxa.clientkill.utils.JsonResult;
import io.swagger.annotations.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author Jun
 * @version 1.0
 * @date 2020/11/11 10:18
 */

    @Api(value = "实现秒杀功能的控制器",tags = "秒杀接口的api")
    @RestController
    @RequestMapping("/kill")

    public class KillController {

            @Resource
            KillService killService;

             //引入jedis/redis-data
             @Resource
             RedisTemplate redisTemplate;

            JsonResult jsonResult = new JsonResult();

        @ApiOperation(value = "修改接口", notes = "秒杀活动的修改", httpMethod = "POST", response = Map.class)
        @ApiResponses({
                @ApiResponse(code = 200, message = "请求成功"),
                @ApiResponse(code = 404, message = "找不到页面"),
                @ApiResponse(code = 415, message = "数据类型格式不正确"),
                @ApiResponse(code = 500, message = "后台服务错误")
        })
        @PostMapping("/update")
        public Map update(@RequestBody @ApiParam(name = "kill",value = "秒杀活动的pojo信息",required = true) Kill kill) {
            Integer update = killService.update(kill);
            jsonResult.setData(kill);
            jsonResult.setCode("200");
            jsonResult.setMsg("修改成功");
            return jsonResult.getValues();
        }

        @PostMapping("/list")
        @ApiOperation(value = "分页查询接口", notes = "用于秒杀活动的列表展示", httpMethod = "POST", response = Map.class)
        @ApiImplicitParams({
                @ApiImplicitParam(name = "limit", value = "分页大小", required = true, dataType = "int", paramType = "query"),
                @ApiImplicitParam(name = "page", value = "当前页", required = true, dataType = "int", paramType = "query")
        })
        @ApiResponses({
                @ApiResponse(code = 200, message = "请求成功"),
                @ApiResponse(code = 404, message = "找不到页面"),
                @ApiResponse(code = 415, message = "数据类型格式不正确"),
                @ApiResponse(code = 500, message = "后台服务错误")
        })
        public Map list(@RequestParam("limit") int limit, @RequestParam("page") int page) {
            //定义一个map
            Map<String, Object> killMap = new HashMap<>();
            //将分页条件输入PageHelper
            Page<Object> page1 = PageHelper.startPage(page, limit);
            //将所有的优惠券信息查询出来
            List<Kill> kills = killService.list();
            //将分页信息与所有的优惠券信息结合
            PageInfo<Kill> info = new PageInfo<>(kills);
            //将分页的列表导入map中
            killMap.put("list",info.getList());
            //将总记录数导入map中
            killMap.put("counts",info.getTotal());
            jsonResult.put("counts",killMap.get("counts"));
            jsonResult.setData(killMap.get("list"));
            jsonResult.setCode("200");
            jsonResult.setMsg("分页查询成功");
            return jsonResult.getValues();
        }


        @PostMapping("/add")
        @ApiOperation(value = "秒杀添加接口", notes = "该接口用于添加秒杀活动", httpMethod = "POST", response = Map.class)
        @ApiResponses({
                @ApiResponse(code = 200, message = "请求成功"),
                @ApiResponse(code = 404, message = "找不到页面"),
                @ApiResponse(code = 415, message = "数据类型格式不正确"),
                @ApiResponse(code = 500, message = "后台服务错误")
        })
        public Map add(@RequestBody @ApiParam(name = "kill",value = "秒杀活动的pojo信息",required = true) Kill kill) {
            killService.add(kill);
            jsonResult.setData(kill);
            jsonResult.setCode("200");
            jsonResult.setMsg("添加成功");
            return jsonResult.getValues();
        }

        @PostMapping("/del")
        @ApiOperation(value = "秒杀删除", notes = "该接口用于删除秒杀", httpMethod = "POST", response = Map.class)
        @ApiImplicitParams({
                @ApiImplicitParam(name = "id", value = "秒杀id", required = true, dataType = "int", paramType = "query"),
        })
        @ApiResponses({
                @ApiResponse(code = 200, message = "请求成功"),
                @ApiResponse(code = 404, message = "找不到页面"),
                @ApiResponse(code = 415, message = "数据类型格式不正确"),
                @ApiResponse(code = 500, message = "后台服务错误")
        })
        public Map del(@RequestParam("id") int id) {
            Integer del = killService.del(id);
            jsonResult.setData(del);
            jsonResult.setCode("200");
            jsonResult.setMsg("删除成功");
            jsonResult.setData(del);
            return jsonResult.getValues();
        }

    @ApiOperation(value = "前台秒杀功能", notes = "该接口用于前台秒杀实现", httpMethod = "POST", response = Map.class)
    @ApiResponses({
            @ApiResponse(code = 200, message = "请求成功"),
            @ApiResponse(code = 404, message = "找不到页面"),
            @ApiResponse(code = 415, message = "数据类型格式不正确"),
            @ApiResponse(code = 500, message = "后台服务错误")
    })
    @PostMapping("/secondSell")
    public Map secondSell(){
        ValueOperations valueOperations = redisTemplate.opsForValue();

        //利用Redis加锁，核心利用NX机制
        Boolean lock = valueOperations.setIfAbsent("lock", true);

        //给用户的锁加上有效时间
        redisTemplate.expire("lock",10, TimeUnit.SECONDS);

//        Boolean lock = valueOperations.setIfAbsent("lock", true, 10, TimeUnit.SECONDS);

        //在实际业务场景中，上述两个操作：setIfAbsent和expire应该用原子级别的操作
        //valueOperations.set("lock",true,10,TimeUnit.SECONDS);
        if (lock){
            //当用户请求到达,判断库存>0
//            valueOperations.set("stock",10);
            Integer stock = (Integer) valueOperations.get("stock");
            System.out.println(stock);

            if (stock>0){
                //库存已经减少
                valueOperations.set("stock",--stock);
                System.out.println("秒杀成功，库存："+stock);
                JsonResult jsonResult = new JsonResult();
                jsonResult.setCode("200");
                jsonResult.setMsg("秒杀成功");

                //添加订单操作
//                valueOperations.set("stock",stock);
                //完成秒杀释放锁资源
                //如果要释放锁，必须是本人
                //原理：在此次发起中生成key（UUID），把key作为作为lock
                //判断当前lock的值是否和此次请求中的key是不是一致
                //如果相等，代表是操作者本人，释放
                //if (uuid.equals(valueOperations.get("lock")))
                redisTemplate.delete("lock");
                return jsonResult.getValues();

            }
        }
        //如果满足库存条件，抢购成功，库存-1

        //用户+id 记录到订单中

        return null;
    }
    }